/* vcc/plugins/ban/ban.c 
 * 
 * This file is part of vcc. 
 * 
 * vcc is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version. 
 * 
 * vcc is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with vcc. If not, see <https://www.gnu.org/licenses/>
 */ 




#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <vcc/vcc.h>
#include <vcc/pretty.h>
#include <vcc/plugin.h>
#include <vcc/interfaces.h>
#include <vcc/version.h>


int do_cmd_ban(int argc, char **argv);
int ban_init(void);

struct cmdtable ban_cmdtab[] = {
	{ "-ban", do_cmd_ban, "Ban control. " }, 

	{ NULL, NULL, NULL }
};

struct plugin plg_ban = {
	.state = 0, 
	.name = "ban", 
	.descr = "Ban / unban somebody. ", 
	.cmdtab = ban_cmdtab, 
	.init = ban_init
};

struct klist_node banned_people = KLIST_NODE_INIT(&banned_people);
#define this_plg (&plg_ban)

static int ban_unban(int argc, char **argv) {
	char 			*name;
	struct klist_node 	*n;
	struct banlist 		*ban;

	switch (argc) {
	case 2:
		name = malloc(USRNAME_SIZE + 1);
		fprintf(stderr, _("Enter the user to ban: "));
		scanf("%s", name);

		break;

	case 3:
		name = argv[2];
		break;

	default:
		fprintf(stderr, "-ban -u [user-name]\n");
		return 1;
	}

	for (n = banned_people.next; n != &banned_people; n = n->next) {
		ban = banlist_of(n);

		if (!strcmp(ban->usrname, name)) {
			klist_del(&banned_people, n);

			free(ban->usrname);
			free(ban);

			break;
		}
	}

	fprintf(stderr, _("User not banned. \n"));
	if (argc == 2) 
		free(name);

	return 0;
}

static int ban_ban(int argc, char **argv) {
	char 			*people_name, people_arr[USRNAME_SIZE];
	struct banlist 		*i;
	struct klist_node 	*n;

	switch (argc) {
	case 2:
		fprintf(stderr, _("Enter the user to ban: "));
		scanf("%s", people_arr);
		people_name = strdup(people_arr);

		break;

	case 3:
		people_name = strdup(argv[2]);

		break;

	default:
		fprintf(stderr, _("usage: -ban -b [user-name]\n"));

		return 1;
	}

	for (n = banned_people.next; n != &banned_people; n = n->next) {
		i = banlist_of(n);

		if (!strcmp(people_name, i->usrname)) {
			fprintf(stderr, _("User %s is already banned\n"), people_name);
			free(people_name);

			return 0;
		}
	}

	if (unlikely(!(i = malloc(sizeof(struct banlist))))) {
		fprintf(stderr, "*** malloc() failed\n");

		return 1;
	}

	i->usrname = people_name;
	klist_init(&i->node);

	klist_add(&banned_people, &i->node);

	return 0;
}

int do_cmd_ban(int argc, char **argv) {
	plg_check_enabled();

	if (cmd_noptions > 1) 
		goto bad_usage;
	if (cmd_options['b']) 
		return ban_ban(argc, argv);
	else if (cmd_options['u']) 
		return ban_unban(argc, argv);

bad_usage:
	fprintf(stderr, "usage: -ban [-b|u] [user-name]\n");
	return 1;
}

char *ban_hook(struct hook_info *hi) {
	struct klist_node *n;
	struct banlist *ban;

	for (n = banned_people.next; n != &banned_people; n = n->next) {
		ban = banlist_of(n);

		if (ban->usrname && !strcmp(ban->usrname, hi->usr)) {
			printf("\nban: message from %s ignored. \n", hi->usr);

			return HOOK_HANDLED;
		}
	}

	return HOOK_IGNORE;
}

int ban_init(void) {
	register_hook(HOOK_RECV, ban_hook);
	return 0;
}


